unit UnitClient;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, IdSync;

type
  TOnReceiverThread = class(TThread)
  protected
    FConexao : TIdTCPConnection;
    procedure Execute; override;
  public
    constructor Create(_Conexao: TIdTCPConnection);reintroduce;
  end;

  TOnProcessa = class(TIdSync)
  protected
    FMsg: string;
    procedure DoSynchronize; override;
  public
    constructor Create(const _Msg:string);
    class procedure AddMsg(const _Msg:string);
  end;

  TFrmCliente = class(TForm)
    mmoText: TMemo;
    edText: TEdit;
    btnEnviar: TButton;
    idTCPClient: TIdTCPClient;
    procedure btnEnviarClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure idTCPClientConnected(Sender: TObject);
    procedure idTCPClientDisconnected(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FrmCliente: TFrmCliente;
  Receiver : TOnReceiverThread;
implementation

{$R *.dfm}

{ TOnReceiverThread }

constructor TOnReceiverThread.Create(_Conexao: TIdTCPConnection);
begin
  FConexao := _Conexao;
  inherited Create(False);
end;

procedure TOnReceiverThread.Execute;
begin
  inherited;
  while not Terminated and FConexao.Connected do
  begin
    TOnProcessa.AddMsg(FConexao.IOHandler.ReadLn);
  end;
  inherited;
end;

{ TOnProcessa }

class procedure TOnProcessa.AddMsg(const _Msg: string);
begin
  with Create(_Msg) do
    try
      Synchronize;
    finally
      Free;
    end;
end;

constructor TOnProcessa.Create(const _Msg: string);
begin
  FMsg := _Msg;
  inherited Create;
end;

procedure TOnProcessa.DoSynchronize;
begin
  inherited;
  FrmCliente.mmoText.Lines.Add(FMsg);
end;

procedure TFrmCliente.btnEnviarClick(Sender: TObject);
begin
  IdTCPClient.IOHandler.WriteLn(edText.Text);
end;

procedure TFrmCliente.FormCreate(Sender: TObject);
begin
  IdTCPClient.Connect;
end;

procedure TFrmCliente.idTCPClientConnected(Sender: TObject);
begin
  Receiver := TOnReceiverThread.Create(IdTCPClient);
end;

procedure TFrmCliente.idTCPClientDisconnected(Sender: TObject);
begin
  if Receiver <> nil then
  begin
    Receiver.Terminate;
    Receiver.WaitFor;
    FreeAndNil(Receiver);
  end;
end;

end.
